マルチブートの仕方(機能編)
また殆どのブートローダはIBMオリジナルのブートストラップローダの制約の回避からスタートしているので、その動作をトラップするために、MBRにインストールする、つまりブートストラップローダを上書きしてしまうのが普通だ。従ってオリジナルブートストラップローダとの共存は普通はできない。しかしLILOはいろいろ選択できるのだが、このブートストラップローダと共存させることもできる。
通常のブートローダはIBMオリジナルブートストラップローダと共存せず、MBRにインストールされ、「パーティション選択」を基本動作として展開される。市販品、フリーツールを問わず、これから紹介するブートローダの殆どは基本的にはこの部類に属す。
まず、ツールの紹介に入る前にブートローダの機能について、お話しておく必要があるだろう。また以下に説明する機能をどのブートローダがサポートしているかは「ブートプログラム(ブートローダ)」を参照してほしい。
IBMオリジナルブートストラップローダは「アクティブな基本パーティションのブートセクターをロードする」ということしかできなかった。これから脱却するにはまず「アクティブでない基本パーティションのブートセクターもロードできる」ようにすればいいのは明白だ。
結局これはアクティブ属性のあるなしに関わらず、基本パーティションの選択ロード機能があればいい訳だ。難しい話ではない。アクティブ属性を無視してブートセクターをロードしてしまえばいいだけだ。起動されたOSからすれば、あたかもそこがアクティブでオリジナルブートストラップローダから起動されたかのようにロードされるだけだ。
ブートローダにとって、これは基本中の基本の機能であって特にこれ以上説明する必要はないね。
これは機能ではなく、使い勝手の話になるが、選択方法はブートローダを選択する上でポイントになることが多いだろう。以下のような種類がある。
ところで、前述の「選択ロード機能」とは実際何をロードするのだろうか。それはパーティションの先頭セクターをロードして、そのセクターにあるであろうOSのIPLに制御を移すという作業を行うだけだ。
このような作業をチェーンロードという。単なるOS-IPLへの繋ぎを行う鎖のような働きをするのでそう呼ばれる。ブートローダの動作の基本は殆どこのチェーンロードだ。とにかく先頭セクターをロードするだけだから、その先のことは何も知らなくてもいい訳だ。そのパーティションがどんなファイルシステムであろうと、実際はファイルシステムなど無かろうと、ブートローダの知ったことではない。
OSのIPLがその後、OSのカーネルなどを読む込むカーネルロードはOS独自のブート手続きの中で行われることだ。ブートローダの中でもあくまでOSブート手続きの一ステージとして位置付けのあるものはこのような作業を行う。たとえばNTLDRはNTのカーネルのロードを行うし、LILOはLinuxカーネルのロードを行う。というよりも、これらのローダはOSのカーネルローダがチェーンロード機能をつけて、他のOSもブートできるようにしたというのが正しい経緯だが。
元々MinixのカーネルローダであったGRUBはチェーンロード機能の追加だけでなく、更に発展して他のOSのカーネルもロードする機能をどんどん追加してきた。しかしこれは非常に珍しいケースで、ブートローダの基本はあくまでチェーンロードであるということは覚えておいてほしい。これはカーネルロードは基本的にはファイルシステムの理解とそれぞれのOSロードの仕組みを理解する必要があり、サードパーティのブートロードにとってはチェーンロードより遥かに難しいからだ。
ところで、アクティブでない基本領域から起動されたOSは実際のところどうなるだろうか。殆どのOSでは起動パーティションがアクティブでないことそれ自身は全く問題ない。
ただし若干のOSではそもそもオリジナルブートストラップローダの仕様から、起動は必ずアクティブパーティションから起動されると信じて、そのような場合しか想定しないで作成してしまったため、非アクティブな領域から起動されると、うまく起動できないものもあるようだ。SCOなどがこの問題があることが確認されている。
もっともMicrosoftのOSでは起動パーティションのアクティブ属性自身はいずれでもいいのだが、ドライブレターの振られ方の関係で実は起動不能、または意図しないパーティションから起動してしまう場合がある。
これはMicrosoftのOSではドライブレターが下図のように、「アクティブな基本領域」->「論理領域」->「非アクティブな基本領域」の順で振られるということと、起動は「Cドライブ」から起動しなければならないという原則があるからだ。
[図1 ドライブレターの振られ方1]
もし上図の例で例えば基本領域2にあるWindows95をローダで起動した場合どうなるだろうか。この場合当然一旦は基本領域2のブートセクターが実行されるが、OS起動プロセスの途中で、Cドライブである基本領域1からデータを読み込もうとする。もしそこに起動するために必要なファイルがない場合、起動が停止してしまう。もしそこにたまたま起動するのに必要なファイルが存在していた場合、たとえば基本領域1にWindows98があった場合、こちらが起動してしまう。いずれにしても意図した起動はされない訳だ。
もし基本領域2から正しくWindows95を起動したい場合、この領域をアクティブにしておき、Cドライブとなるようにしておかねばならない。
[図2 ドライブレターの振られ方2]
図2のように基本領域2をアクティブにした上で、基本領域2のブートセクターをロードすれば、意図したように基本領域2にあるWindows95が起動する。
同様に基本領域1にあるWindows98を起動したい場合は図1のように基本領域1をアクティブにした上で、この領域のブートセクターをロードする必要がある訳だ。
多くのブートローダがこのアクティブ領域の切り替えをブート時に自動的に行うようになっている。ブートローダの非常に基本的で代表的な機能の一つであるといえる。Cドライブからしか起動しないMicrosoftのOSを起動するために非常に重要な機能だ。
因みにドライブレターの振られ方については「ドライブレターの詳細」で詳しく説明しているので、合わせてよく読んでおいてほしい。
最近はOS/2も宣伝は全然見なくなった。もう風前の灯なのだろうか。そんなOSだがブートにとって非常に興味深い機能を考案している。OS/2が標準で持っているブートの仕組みというかツールとしてブートマネージャというものがあるが、これが隠しパーティション(Hidden Partition)という面白い機能を作り出したのだ。
もっとも、考案したというよりも、こうするしか無かったといった方がいいかもしれない。先ほどNTLDRやLILOは異色だと述べたが、実はこのブートマネージャも非常に特異なブートローダだ。基本的にIBMオリジナルのブートストラップローダはいじらずにマルチブートを実現しようとしたため、大きな制約を生んだ。
ブートマネージャではまずブートマネージャ専用の基本領域を一つ必要とする。そしてこのブートマネージャ専用基本領域をアクティブとしておき、MBRのブートストラップローダにロードしてもらう。そこでブートマネージャに制御が来るので、このローダが動き出し、パーティションの選択フェーズへ進み、ユーザがパーティションを選択して、選択されたパーティションのブートセクターをロードする。
という手順なので、このブートマネージャ専用の基本領域は常にアクティブにしておかねばならない。もし別の領域がアクティブになると次回ブートマネージャが実行されない。結局前述したアクティブ切り替えはブートマネージャではできない訳だ。当然前述したようなMicrosoftのOSの起動に支障をきたす。
そこで考案されたのが隠しパーティションなのだ。そこにはやはり、次のようなMicrosoftOSのドライブレターの振られ方の性質が利用されている。
前に非アクティブな基本領域は論理領域よりも後になると説明したが、もしアクティブな基本領域がない場合は非アクティブ基本領域でも論理領域よりも先になる。だから正確に言うと、「ドライブレターの詳細」でも触れているが、以下のようになる。
また上記ページでも触れている通り、そのOSが知らないパーティションタイプの領域は無視され、無いものと同じように扱われる。図示すると以下のようになる。
[図3 ドライブレターの振られ方3]
この例では基本領域1はアクティブだが、起動OSが知らないパーティションタイプだ。たとえばWindows98はFAT16とFAT32しか知らないので、もしこの領域がNTFSだった場合、「知らない領域」ということになる。知らない領域はたとえアクティブでも決してドライブレターが振られることはない。あとは残りの基本領域のうち、先頭の領域がCドライブになる。
この性質を利用すれば、アクティブ属性を変更しないでも、目的のパーティションをCドライブにすることができる。ブートマネージャの領域は「0x0A」というパーティションなので、全てのMicrosoftのOSからすれば、「知らない領域」になる。そこがアクティブであってもCドライブにはならない。後は目的のパーティションがCドライブになるように、そのほかのパーティションも隠してしまう。
たとえば図3の例の場合、基本領域2からWindows95を起動するには特に何もする必要はない。例のように既にCドライブになっているからだ。ではもし基本領域3にWindows98があったとして、この領域をCドライブにするにはどうしたらいいのだろうか。そう、基本領域2も隠しパーティションにしてしまえばいい訳だ。
隠しパーティションとは要はどのOSから見ても「知らない領域」ということで全然未知のパーティションタイプをもつパーティションのことだ。具体的には元のパーティションタイプに0x10との論理和をとって(技術的な言葉で言うと、上位ニブルの最下位ビットを立てる)、これとすり替えてしまう訳だ。表にすると以下のようになる。
FAT12 | FAT16 | FAT16(big) | FAT16X | FAT32 | FAT32X | NTFS/HPFS | |
正規のパーティションタイプ | 01 | 04 | 06 | 0E | 0B | 0C | 07 |
隠しパーティションタイプ | 11 | 14 | 16 | 1E | 1B | 1C | 17 |
上記の表と図を元にもっと具体的に説明しよう。以下の実際ブートマネージャを用いたWindows95、Windows98、OS/2のトリプルブートの場合のパーティション構成を示す。
[図4 Windows95、Windows98、OS/2 Warpのトリプルブートのパーティション構成]
ひとつの基本領域をまずブートマネージャが占有する。またこの領域がアクティブとなるのは説明した。他の3つの基本領域にそれぞれをOSをインストールする訳だが、上記の例では基本領域2のOS/2 Warpが起動している場面だ。基本領域1のFAT16はこの時点ではパーティションタイプ「16」になっており、また基本領域3のFAT32も「1B」なっている。本来OS/2はFAT16を理解できるので、もしパーティションタイプが「06」だった場合、見えてしまう。しかし「16」という未知のパーティションタイプになっているので、見えない訳だ。
基本領域3のWindows98を起動した場合、この領域は「0B」に戻され一方基本領域2は「17」として隠しパーティションとされる。
今まで説明してきたように、隠しパーティションがドライブレターの振られ方からくる特定のパーティションをCドライブにするための手段ということなら、たとえばCドライブにしたい目的のパーティションの後ろにある基本領域なら別に隠しパーティションにする必要はない。たとえば図4の例の場合、基本領域1のWindows95を起動した時は基本領域3を隠しパーティションにする必要ない。
しかしOSのインストール時には特にMicrosoftのOSのインストール時にはインストールパーティション以外の基本領域は隠しパーティションにするのが必須と考えた方がいいだろう。インストール時何かとトラブルが多いでの他の基本領域はなるべく隠しておいた方が無難である。
ただし、主目的が「アクティブ切り替え」でも代替できる場合が多いのでこの機能をサポートするローダはそれほど多くはない。またサポートする場合も隠しパーティションへの切り替えを起動時に自動的に行うもの(起動基本領域以外は無条件で隠しにするもの、または設定によって動作を変更できるもの)、起動時に手動で変更するものなど、動作は様々である。
因みに「隠しパーティション」のことを、ツールによっては「非表示パーティション」などと表現する場合もある。PartitionMagicなどではそのように呼んでいる。あまり適切な表現とは思えないが、ツールがそう呼んでいる以上、覚えておくほかない。
英語では「Hidden」(hideの過去分詞)が一般的だが、「mask」と表現される場合も多い。特に後者は日本語でも、そのまま隠しパーティションにすることを「パーティションをマスクする」と表現することもかなり一般的に行われるから、合わせて覚えておいてほしい。
論理領域の場合、そのチェーン構造のために位置を辿るのが面倒になる。もっともブートローダにとって、これ自体は全然難しいことではないのだが、最も問題なのは基本的にブートローダはOSのブートセクターを読み込んで、そこに制御を移したら、後はそのOSの起動プロセスに任せるほかなく、起動が成功するかしないかは最後はOS独自のブートプロセスにかかっていることだ。
実は多くのOSが、論理領域からの起動を想定した作りになっていないので、いくらブートローダが、そのような位置にあるOSのブートセクターを読んで実行してあげても、その後のOS独自のブートプロセスの中で、自分の位置を見失ってしまうのだ。
現在のところ、論理領域起動が可能なOSはLinuxかBeOS及びOS/2くらいだろう。従ってブートローダとしてもあまり需要がないせいか、それほど難しいことではないとはしても、サポートしていないものも多い。ただLinuxの普及度を考えると、だんだん重要な機能になってきたと思う。
OS次第ということでは論理領域起動と同じなのだが、これよりは問題が少ないようで、第2ハードディスク以降からの起動をサポートするOSは多いのが、第2ハードディスク以降からのOSの起動である。特にLinuxをはじめUNIX系OSでは問題のないものが多いようだ。
Windowsなどはシステムディレクトリは論理領域同様、これを第2ハードディスク以降に置くことは殆ど問題ないのだが、ブート系ファイルを置くことは基本的にできない。全くOSが対応しておらず、Microsoftとしてサポート対象外のインストール方法ということになる。しかし多くのブートローダが裏技を使って、このOSベンダー自身がサポートしていないWindows系OSの第2ハードディスク以降からの起動を可能にしている。
裏技はいくつか方法があるようだが、最も一般的なのが、ドライブIDのスワップだ。BIOSで認識している、ドライブの番号(ID)を第1ハードディスクと第2ハードディスクですりかえてしまおうというものだ。BIOSレベルですかえてしまうので、OSローダから見るとそのことが全く分からない。これは裏技というよりも、OSローダを騙している訳である。
ただしドライブスワップといっても、その実装方法にはいくつかあり、これで完璧というリファレンスはない。大体が「BIOSのフック」と俗に呼ばれる方法だ。まあメモリ上に罠を仕掛けると思ってもらっていいだろう。そもそもOSがサポートしていない動作を何とか誤魔化してやろうというのだから、完璧な方法というのはあり得ないのかもしれない。また何とか動いていても、その後新しいOSでは動作しなくなるということが十分に考えられる。
だから同じようにドライブスワップ方式を採用していても、各ローダで実装が異なっているため、第2ハードディスク以降のWindows系のOSの起動にはかなり違いがある。以下に第2ハードディスク起動のサポートを謳っているローダについて実際私の環境での動作結果を記載してみた。一応複数のマシンでほぼ同じ現象がおきているので、ある程度信頼できる情報だと思う。環境によっては症状が多少違ったりはすると思う。
[第2ハードディスクからのWindows系OSの起動]
Windows9x | WindowsME | WindowsNT | Windows2000 | |
LILO | ○ | ○ | ○ | ○ |
MBM | ○ | ○ | ○ | ○ |
Ext-IPL | ○ | ○ | ○ | ○ |
BootIt | ○ | ○ | ○ | ○ |
システムコマンダー | ○*3 | × | × | × |
Boot Magic | ○*3 | ○*3 | × | × |
SBM | △*2 | △*2 | ○ | ○ |
GRUB | △*2 | △*1 | ○ | ○ |
XOSL | △*2 | △*2 | ○ | ○ |
GAG | △*2 | △*2 | ○ | ○ |
*1 ブートはするが、起動の途中で止まる。
*2 OSも完全に起動するが、MS-DOS互換モードになってしまう。
*3 第1ハードディスクのFAT基本領域を隠す必要がある。
結局メモリ上に仕掛けた罠が、OS起動の過程、または起動後にも何らかの問題を引き起こしてしまうのだろう。このあたり各ローダ開発者も、どこに罠をしかけるかを工夫しているのだが、なかなかベストな位置がないのかもしれない。
しかし何とかこのような方法でブートできた場合でも、WindowsNT系ではドライブレターの振られ方などがめちゃくちゃになるなど、様々な面で動作に支障をきたすため、一部のローダ(システムコマンダーやBoot Magicなど)ではあえてサポートしてないし、マニュアルでもはっきりと「できない」と書いてある。私もWindowsNT系の第2ハードディスク起動はあまりお薦めしない。因みに最新のBoot Magicは実際は上記のように動くが、以前のようにこれについての記述がマニュアルから消えている。きっとサポートをやめたのだろう。
また起動後のOSの挙動とも無関係ではない可能性があるので、たとえ首尾よく起動できたとしても、その後の運用上どのような支障が生じるかは予想ができない。重要な作業で使うOSはやはり第1ハードディスクからの起動にしておくのが無難だと思う。
因みにOSを騙しているのはOSロードの極初期段階だけだ。OSもカーネルが本格的に動き出すともうBIOSを頼ってハードディスクにアクセスするのではなく、独自のドライバを用いてアクセスを始める。こうなるともはやBIOSの世界である、第1ハードディスクとか第2ハードディスクという概念はなくなり、「IDEのプライマリーマスターのハードディスク」とか「SCSIのID何番のハードディスク」といった正しい接続位置を認識しだすので上記の動作はお役ご免となる。
これは一つのパーティションにFAT互換のOSの多数インストールする機能だ。原理的には「Windows9xをNTLDRでマルチする」でやっていることと若干似ているのだが、こちらは起動時にダイナミックにOSローダ(IO.SYSやMSDOS.SYSなど)を変えてしまうというものだ。
Windows9x系のOSを沢山インストールしたいという向きには結構便利な機能かもしれない。前述のような第2ハードディスク以降に置けない場合が多く、OS自身がLBAに対応していない古いものを使う場合、ハードディスクの先頭のパーティションに複数突っ込みたいと思う人も多いだろう。
しかしIO.SYSなどをコピーしたり、書き換えたりするので、当然ファイルシステムFATを理解する必要があるため、ローダのコードサイズがどうしても大きくなる。現在のところフリーのローダでこの機能をサポートしているものは見たことがない。
また「Multi-FAT機能」という呼び名も定着したものではない。これはSystem Commanderでの呼び方を流用した。ブートローダによって、この機能の呼び方は様々(BootItでは「マルチOS機能」と呼んでいる)なので注意してほしい。
また私は「Multi-FAT機能」には大きく大別して、「限定Multi-FAT機能」と「完全Multi-FAT機能」の2つがあると思っている。
「限定Multi-FAT機能」とは基本的にはマルチブートの機能がなく、1つのOSにつき必ず一つのFAT基本領域を必要とするWindows9x系のために、Cドライブに置くことが必須であるIO.SYSやMSDOS.SYSなどのブート系ファイルだけをダイナミックに変更する機能だ。この場合、システムディレクトリ(Windowsディレクトリ)は別々の論理領域にインストールすることを前提にしている。これによって「Program Filesディレクトリ」もそれぞれ別の論理領域にインストールされ、各OSで共有することがなくなる。
「Program Filesディレクトリ」は本来アプリケーションがデフォルトがインストールされる場所なので、各OSで別々にすることが望ましいものだ。アプリケーションにより、対応OSが異なることが多いからだ。システムディレクトリは名称を変更できるため、一つのパーティションに各OSのものをインストールしてしまうことも可能だが、「Program Filesディレクトリ」は名称変更ができず、一つのパーティションにシステムディレクトリを入れてしまうと、そのOS間で「Program Filesディレクトリ」を共有することになってしまう。アプリケーションの安全上これは好ましくないので、システムディレクトリを別のパーティションにすることにより「Program Filesディレクトリ」を分けた方がいいということになる。
従って、「限定Multi-FAT機能」の場合、安全に運用するにはOSの数に応じた数の論理パーティションを必要とする。論理パーティションは理論上無限に作成できるので実用上は問題ないと思うが、そのようなある程度限定された機能であるということになる。
ただし、例えばWindows98とWindows98 SEなどのようにOSの性質が殆ど同じであるため、実際「Program Filesディレクトリ」を共有しても、殆ど問題のない組み合わせもある。
一方「完全Multi-FAT機能」は名実共に一つのFATパーティションに複数のWindows9x系をインストールするための機能でブート系ファイルだけでなく、この「Program Filesディレクトリ」もダイナミックに変更する機能を提供する。これによって、安全に、かつ完全に一つのFATパーティションでWindows9xのマルチブートを可能にするものだ。
現在のところ「完全Multi-FAT機能」を持っているのはSystem Selectorくらいだろう。System CommanderもBootItも「限定Multi-FAT機能」だ。もっともSystem Commanderではそもそも複数のWindows9xをインストールするためにMulti-FAT機能を用意している訳ではないようである。マニュアルにはこのような用途に使うためであるという記述は一切見つけることはできない。
「Multi-FAT環境の構築」ではSystem Commanderの場合の環境構築の話をしているので、興味のある人は参照してほしい。
その他、細かな機能で実はあったら便利というものはいくつかある。